package com.sxj.corejava.code08_常用类.日期类;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * @author 石小俊
 * @date 2025年01月11日
 * 日期工具类
 */
public class DateUtil {

    /**
     * 将日期转换成字符串,使用方法重载定义两个方法
     * @param date    转换前的日期
     * @param pattern 转换后的字符串格式
     * @return 转换后的字符串
     */
    public static String toString(Date date, String pattern) {
        return new SimpleDateFormat(pattern).format(date);
    }

    /**
     * 转换成一个默认格式的字符串,默认格式通过常量来定义,默认格式设置为yyyy-MM-dd HH:mm:ss
     * @param date 转换前的日期
     * @return 转换后的字符串
     * @see DateConstant
     */
    public static String toString(Date date) {
        return toString(date, DateConstant.DATE_DEFAULT_PATTERN);
    }

    /**
     * 将一个字符串转换成日期
     * @param dateStr 转换前的字符串
     * @param pattern 字符串格式
     * @return 转换后的日期
     */
    public static Date toDate(String dateStr, String pattern) throws ParseException {
        return new SimpleDateFormat(pattern).parse(dateStr);
    }

    /**
     * 将一个默认格式的字符串转换成日期
     * @param dateStr 转换前的字符串
     * @return 转换后的日期
     * @see DateConstant
     */
    public static Date toDate(String dateStr) throws ParseException {
        return toDate(dateStr, DateConstant.DATE_DEFAULT_PATTERN);
    }

    /**
     * 计算指定日期的前一天
     * @param date 指定日期
     * @return 前一天的日期
     */
    public static Date getYesterday(Date date) {
        long time = date.getTime() - DateConstant.ONE_DAY_MILLISECOND;
        return new Date(time);
    }

    /**
     * 计算指定日期的下一天
     * @param date 指定日期
     * @return 下一天的日期
     */
    public static Date getNextDay(Date date) {
        long time = date.getTime() + DateConstant.ONE_DAY_MILLISECOND;
        return new Date(time);
    }

    /**
     * 计算两个日期之间相差的天数,不足一天的以一天算
     * @param startDate 第一个日期
     * @param endDate   第二个日期
     * @return 相差的天数
     */
    public static int getDuringDay(Date startDate, Date endDate) {
        // 计算两个日期之间毫秒数的差值
        int day = 0;
        // 方式一
        // 通过该毫秒数除以一天的毫秒数
//        long time = endDate.getTime() - startDate.getTime();
//        if(time % DateConstant.ONE_DAY_MILLISECOND == 0){
//            day = (int) (time / DateConstant.ONE_DAY_MILLISECOND);
//        } else{
//            day = (int) (time / DateConstant.ONE_DAY_MILLISECOND + 1);
//        }

        // 方式二
        // 判断开始日期是否比结束日期早
        while (startDate.before(endDate)) {
            // 如果早,取开始日期的下一天
            startDate = getNextDay(startDate);
            // 且相差的天数+1
            day++;
        }
        return day;
    }

    /**
     * 计算两个日期之间相差的天数,直接截掉
     * @param startDate 第一个日期
     * @param endDate   第二个日期
     * @return 相差的天数
     */
    public static int getDuringDay2(Date startDate, Date endDate) {
        // 计算两个日期之间毫秒数的差值
        long time = endDate.getTime() - startDate.getTime();
        // 通过该毫秒数除以一天的毫秒数
        int day = (int) (time / DateConstant.ONE_DAY_MILLISECOND);
        return day;
    }

    /**
     * 获取日期中指定的年、月、日、时、分、秒的值
     * @param date  指定日期
     * @param field 需要返回的哪一部分的值
     * @return 指定部分的具体的值
     * @see DateConstant
     */
    public static int get(Date date, int field) {
        // 将日期转换成字符串
        String s = toString(date);
        // 将该日期字符串根据-、空格、冒号进行分割,每一部分组做数组的一个元素
        String[] arr = s.split("[-\\s:]");
        return Integer.parseInt(arr[field]);
    }

    /**
     * 在DateUtil工具类中新增一个方法
     * 根据指定的年份year与月份month获取year年month月共有多少天
     * @param year
     * @param month 月份:1-12月
     * @return
     */
    public static int getDay(int year, int month) {
        // 设置日历对象
        Calendar calendar = Calendar.getInstance();
        // 设置日历的年份
        calendar.set(Calendar.YEAR, year);
        // 设置日历的月份,其值是0-11,此处需要-1
        calendar.set(Calendar.MONTH, month - 1);
        return calendar.getActualMaximum(Calendar.DATE);
    }

    /**
     * 在DateUtil工具类中新增一个方法
     * 根据指定的年份year与月份month获取year年month月共有多少天
     * 要求不允许使用getActualMaximum方法实现
     * @param year
     * @param month 月份:1-12月
     * @return
     */
    public static int getDay2(int year, int month) {
        // 设置日历对象
        Calendar calendar = Calendar.getInstance();
        // 设置日历的年份
        calendar.set(Calendar.YEAR, year);
        // 设置为本月的最后一天,即:下一个月的第一天的前一天
        // 设置下一个
//        calendar.set(Calendar.MONTH, month - 1 + 1);
        calendar.set(Calendar.MONTH, month);
        // 下一个月的第一天的前一天
//        calendar.set(Calendar.DATE,1 - 1);
        calendar.set(Calendar.DATE, 0);
        // 获取当天是本月的第一天,由于当天是本月的最后一天
        // 因此,获取的天数即为本月共有多少天
        return calendar.get(Calendar.DATE);
    }


    public static void main(String[] args) throws ParseException {
        Date date = new Date();
        System.out.println(DateUtil.toString(date));
        System.out.println(DateUtil.toString(date, "yyyy年MM月dd日 HH:mm:ss"));

        String dateStr = "2025年02月18日 15:15:35";
        Date date2 = DateUtil.toDate(dateStr, "yyyy年MM月dd日 HH:mm:ss");
        System.out.println(date2);
        String dateStr2 = "2025-03-17 15:15:35";
        Date date3 = DateUtil.toDate(dateStr2);
        System.out.println(date3);

        System.out.println(DateUtil.getYesterday(date));
        System.out.println(DateUtil.getNextDay(date));
        System.out.println(DateUtil.toString(DateUtil.getYesterday(date)));
        System.out.println(DateUtil.toString(DateUtil.getNextDay(date)));
        System.out.println(date);
        System.out.println(date3);
        System.out.println(DateUtil.getDuringDay(date, date3));
        System.out.println(DateUtil.getDuringDay2(date, date3));
        System.out.println(DateUtil.toString(date));
        System.out.println("年份:" + DateUtil.get(date, DateConstant.YEAR));
        System.out.println("月份:" + DateUtil.get(date, DateConstant.MONTH));
        System.out.println("天数:" + DateUtil.get(date, DateConstant.DAY));
        System.out.println("小时数:" + DateUtil.get(date, DateConstant.HOURS));
        System.out.println("分钟数:" + DateUtil.get(date, DateConstant.MINUTE));
        System.out.println("秒数:" + DateUtil.get(date, DateConstant.SECONDS));
    }
}
